package com.dstz.bpm.core.manager.impl;

import com.dstz.base.api.query.QueryFilter;
import com.dstz.base.core.id.IdUtil;
import com.dstz.base.core.util.StringUtil;
import com.dstz.base.core.util.ThreadMapUtil;
import com.dstz.base.manager.impl.BaseManager;
import com.dstz.bpm.act.service.ActInstanceService;
import com.dstz.bpm.api.constant.InstanceStatus;
import com.dstz.bpm.api.model.def.IBpmDefinition;
import com.dstz.bpm.core.dao.BpmInstanceDao;
import com.dstz.bpm.core.manager.BpmBusLinkManager;
import com.dstz.bpm.core.manager.BpmInstanceManager;
import com.dstz.bpm.core.manager.BpmTaskManager;
import com.dstz.bpm.core.manager.BpmTaskOpinionManager;
import com.dstz.bpm.core.manager.BpmTaskStackManager;
import com.dstz.bpm.core.model.BpmBusLink;
import com.dstz.bpm.core.model.BpmInstance;
import com.dstz.bpm.core.model.BpmTaskApprove;
import com.dstz.bus.api.model.IBusinessObject;
import com.dstz.bus.api.service.IBusinessDataService;
import com.dstz.bus.api.service.IBusinessObjectService;
import com.dstz.org.api.model.IUser;
import com.dstz.sys.util.ContextUtil;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import javax.annotation.Resource;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service("bpmInstanceManager")
public class BpmInstanceManagerImpl extends BaseManager<String, BpmInstance> implements BpmInstanceManager {
   @Resource
   BpmInstanceDao g;
   @Autowired
   BpmTaskManager h;
   @Autowired
   ActInstanceService i;
   @Autowired
   BpmTaskOpinionManager j;
   @Autowired
   BpmTaskStackManager k;
   @Autowired
   BpmBusLinkManager l;
   @Autowired
   IBusinessDataService m;
   @Autowired
   IBusinessObjectService n;

   public boolean isSuspendByInstId(String instId) {
      return false;
   }

   public List<BpmInstance> getApplyList(String userId, QueryFilter queryFilter) {
      queryFilter.addParamsFilter("userId", userId);
      return this.g.getApplyList(queryFilter);
   }

   public List<BpmTaskApprove> getApproveHistoryList(String userId, QueryFilter queryFilter) {
      queryFilter.addParamsFilter("approver", userId);
      return this.g.getApproveHistoryList(queryFilter);
   }

   public BpmInstance getTopInstance(BpmInstance instance) {
      if (instance != null && !StringUtil.isZeroEmpty(instance.getParentInstId())) {
         BpmInstance parentInstance = (BpmInstance)this.get(instance.getParentInstId());
         BpmInstance topInstance = this.getTopInstance(parentInstance);
         return topInstance != null ? topInstance : parentInstance;
      } else {
         return null;
      }
   }

   @Override
   public void create(BpmInstance entity) {
      entity.setCreateOrgId(ContextUtil.getCurrentGroupId());
      super.create(entity);
   }

   public BpmInstance genInstanceByDefinition(IBpmDefinition bpmDefinition) {
      BpmInstance instance = new BpmInstance();
      instance.setId(IdUtil.getSuid());
      instance.setSubject(bpmDefinition.getName());
      instance.setDefId(bpmDefinition.getId());
      instance.setTypeId(bpmDefinition.getTypeId());
      instance.setDefKey(bpmDefinition.getKey());
      instance.setActDefId(bpmDefinition.getActDefId());
      instance.setDefName(bpmDefinition.getName());
      instance.setStatus(InstanceStatus.STATUS_RUNNING.getKey());
      IUser user = ContextUtil.getCurrentUser();
      instance.setCreateBy(user.getUserId());
      instance.setCreator(user.getFullname());
      instance.setCreateTime(new Date());
      instance.setSupportMobile(bpmDefinition.getSupportMobile());
      instance.setParentInstId("0");
      if (bpmDefinition.getStatus().equals("deploy")) {
         instance.setIsFormmal("Y");
      } else if (bpmDefinition.getStatus().equals("draft")) {
         instance.setIsFormmal("N");
      }

      instance.setHasCreate(false);
      return instance;
   }

   public List<BpmInstance> getByPId(String parentInstId) {
      return this.g.getByPId(parentInstId);
   }

   public BpmInstance getByActInstId(String actInstId) {
      return this.g.getByActInstId(actInstId);
   }

   public void delete(String arrIds) {
      if (!StringUtil.isEmpty(arrIds)) {
         String[] ids = arrIds.split(",");
         String[] var3 = ids;
         int var4 = ids.length;

         for(int var5 = 0; var5 < var4; ++var5) {
            String id = var3[var5];
            if (!StringUtil.isEmpty(id)) {
               BpmInstance inst = (BpmInstance)this.get(id);
               if (inst != null) {
                  BpmInstance topInst = this.getTopInstance(inst);
                  if (topInst != null) {
                     this.b(topInst);
                  } else {
                     this.b(inst);
                  }
               }
            }
         }

      }
   }

   private void b(BpmInstance instance) {
      String instId = instance.getId();
      this.remove(instId);
      this.h.removeByInstId(instId);
      this.j.removeByInstId(instId);
      this.k.removeByInstanceId(instId);
      List<BpmBusLink> links = this.l.getByInstanceId(instId);
      Iterator var4 = links.iterator();

      while(var4.hasNext()) {
         BpmBusLink link = (BpmBusLink)var4.next();
         IBusinessObject bo = this.n.getFilledByKey(link.getBizCode());
         if (bo != null) {
            this.m.removeData(bo, link.getBizId());
            this.l.remove(link.getId());
         }
      }

      ThreadMapUtil.put("AgileBPMDeleteInstance", true);
      if (StringUtil.isNotEmpty(instance.getActInstId()) && this.i.getProcessInstance(instance.getActInstId()) != null) {
         this.i.deleteProcessInstance(instance.getActInstId(), String.format("用户：%s[%s]执行删除实例", ContextUtil.getCurrentUser().getFullname(), ContextUtil.getCurrentUser().getAccount()));
      }

      List<BpmInstance> subInsts = this.getByPId(instId);
      Iterator var8 = subInsts.iterator();

      while(var8.hasNext()) {
         BpmInstance subInst = (BpmInstance)var8.next();
         this.b(subInst);
      }

   }

   public List<BpmInstance> getByParentId(String id) {
      return this.g.getByPId(id);
   }

   public void toForbidden(String instId, boolean forbidden) {
      List<BpmInstance> bpmInstanceList = this.listParentAndSubById(instId);
      if (CollectionUtils.isNotEmpty(bpmInstanceList)) {
         Date updateTime = new Date();
         String updateBy = ContextUtil.getCurrentUserId();
         Iterator var6 = bpmInstanceList.iterator();

         while(var6.hasNext()) {
            BpmInstance bpmInstance = (BpmInstance)var6.next();
            if (InstanceStatus.STATUS_RUNNING.getKey().equalsIgnoreCase(bpmInstance.getStatus())) {
               bpmInstance.setUpdateBy(updateBy);
               bpmInstance.setUpdateTime(updateTime);
               bpmInstance.setIsForbidden(forbidden ? BpmInstance.INSTANCE_FORBIDDEN : BpmInstance.INSTANCE_NO_FORBIDDEN);
               this.g.update(bpmInstance);
            }
         }
      }

   }

   public List<BpmInstance> listParentAndSubById(String instId) {
      BpmInstance bpmInstance = (BpmInstance)this.g.get(instId);
      if (bpmInstance == null) {
         return new ArrayList();
      } else {
         List<BpmInstance> bpmInstanceList = new ArrayList();
         bpmInstanceList.add(bpmInstance);
         LinkedList<BpmInstance> linkedList = new LinkedList();
         linkedList.push(bpmInstance);

         BpmInstance parentBpmInstance;
         while(!linkedList.isEmpty()) {
            parentBpmInstance = (BpmInstance)linkedList.pop();
            if (StringUtils.isNotEmpty(parentBpmInstance.getParentInstId()) && !StringUtils.equals(parentBpmInstance.getParentInstId(), "0")) {
               parentBpmInstance = (BpmInstance)this.g.get(parentBpmInstance.getParentInstId());
               if (parentBpmInstance != null) {
                  bpmInstanceList.add(parentBpmInstance);
                  linkedList.push(parentBpmInstance);
               }
            }
         }

         linkedList.push(bpmInstance);

         while(!linkedList.isEmpty()) {
            parentBpmInstance = (BpmInstance)linkedList.pop();
            List<BpmInstance> subBpmInstanceList = this.g.getByPId(parentBpmInstance.getId());
            if (CollectionUtils.isNotEmpty(subBpmInstanceList)) {
               linkedList.addAll(subBpmInstanceList);
               bpmInstanceList.addAll(subBpmInstanceList);
            }
         }

         return bpmInstanceList;
      }
   }

}
